<template>
	<div class="dept-tree-container">
		<div class="dept-tree-header">
			<div class="header-left">
				<span class="dept-tree-title">{{ title }}</span>
				<!-- 公司选择器 -->
				<div v-if="showCompanySelector" class="company-selector">
					<el-select
						v-model="selectedCompany"
						placeholder="请选择公司"
						size="small"
						style="width: 120px; margin-left: 8px"
						@change="handleCompanyChange"
						clearable
					>
						<el-option v-for="company in companyList" :key="company.Value" :label="company.Text" :value="company.Value" />
					</el-select>
				</div>
			</div>
			<el-button v-if="showRefresh" link size="small" @click="refreshTree">
				<i class="fa fa-refresh"></i>
			</el-button>
		</div>
		<div class="dept-tree-content">
			<!-- 骨架图 -->
			<div v-if="loading" class="tree-skeleton">
				<div v-for="level in 3" :key="level" class="skeleton-level">
					<div v-for="item in level === 1 ? 2 : level === 2 ? 3 : 4" :key="item" class="skeleton-node" :class="`level-${level}`">
						<div class="skeleton-icon"></div>
						<div class="skeleton-text" :style="{ width: `${60 + Math.random() * 40}px` }"></div>
					</div>
				</div>
			</div>

			<!-- 空状态 -->
			<div v-else-if="treeData.length === 0" class="empty-state">
				<i class="fa fa-folder-open-o empty-icon"></i>
				<p class="empty-text">暂无部门数据</p>
			</div>

			<!-- 实际树组件 -->
			<el-tree
				v-else
				ref="treeRef"
				:data="treeData"
				:props="treeProps"
				:default-expand-all="defaultExpandAll && !expandFirstLevel"
				:default-expanded-keys="expandFirstLevel ? defaultExpandedKeys : []"
				:expand-on-click-node="false"
				:highlight-current="true"
				:indent="16"
				node-key="Value"
				@node-click="handleNodeClick"
				class="dept-tree"
			>
				<template #default="{ node, data }">
					<div class="tree-node-content">
						<i :class="getNodeIcon(node)" class="node-icon"></i>
						<el-tooltip :content="node.label" :disabled="!isTextOverflow(node.label)" placement="right" effect="dark">
							<span class="node-label">{{ node.label }}</span>
						</el-tooltip>
						<span v-if="showCount && data.Count" class="node-count">({{ data.Count }})</span>
					</div>
				</template>
			</el-tree>
		</div>
	</div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue';
import other from '/@/utils/other';
import { commonApi, Organization } from '/@/api/common';

interface TreeNode {
	Value: string | number;
	Text: string;
	Children?: TreeNode[];
	Count?: number;

	[key: string]: any;
}

// 使用Organization类型替代Company
type Company = Organization;

interface Props {
	/** 树形菜单标题 */
	title?: string;
	/** 是否显示刷新按钮 */
	showRefresh?: boolean;
	/** 是否显示节点数量 */
	showCount?: boolean;
	/** 是否默认展开所有节点 */
	defaultExpandAll?: boolean;
	/** 是否只展开第一级节点 */
	expandFirstLevel?: boolean;
	/** 自定义数据源API */
	dataSource?: string;
	/** 静态数据 */
	data?: TreeNode[];
	/** 初始选中的节点 */
	defaultSelected?: string | number;
	/** 组织ID，可选 */
	orgId?: string | number;
	/** 是否启用认证，默认为true */
	auth?: boolean;
	/** 是否显示公司，默认为false */
	showCompany?: boolean;
	/** 是否显示公司选择器 */
	showCompanySelector?: boolean;
	/** 默认选中的公司ID */
	defaultCompanyId?: string | number;
}

const props = withDefaults(defineProps<Props>(), {
	title: '部门列表',
	showRefresh: false,
	showCount: false,
	defaultExpandAll: false,
	expandFirstLevel: false,
	dataSource: '/api/common/GetGroups',
	data: () => [],
	defaultSelected: '',
	orgId: undefined,
	auth: true,
	showCompany: false,
	showCompanySelector: true,
	defaultCompanyId: '',
});

const emit = defineEmits<{
	/** 节点点击事件 */
	nodeClick: [node: TreeNode, nodeData: any];
	/** 数据加载完成事件 */
	dataLoaded: [data: TreeNode[]];
	/** 公司选择变化事件 */
	companyChange: [companyId: string | number, company: Company | null];
}>();

const loading = ref(false);
const treeRef = ref();
const treeData = ref<TreeNode[]>([]);
const companyList = ref<Company[]>([]);
const selectedCompany = ref<string | number>('');
const defaultExpandedKeys = ref<(string | number)[]>([]);

const treeProps = {
	children: 'Children',
	label: 'Text',
	value: 'Value',
	disabled: 'Disabled',
};

// 获取节点图标
const getNodeIcon = (node: any) => {
	if (node.isLeaf) {
		return 'fa fa-user';
	}
	return node.expanded ? 'fa fa-folder-open' : 'fa fa-folder';
};

// 判断文本是否溢出
const isTextOverflow = (text: string) => {
	return text && text.length > 8;
};

// 获取第一级节点的键值
const getFirstLevelKeys = (nodes: TreeNode[]): (string | number)[] => {
	return nodes.map((node) => node.Value);
};

// 处理节点点击
const handleNodeClick = (data: TreeNode, node: any) => {
	emit('nodeClick', data, node);
};

// 处理公司选择变化
const handleCompanyChange = async (companyId: string | number) => {
	if (companyId) {
		// 更新orgId并重新加载树形数据
		await loadTreeData();
		// 触发公司变化事件
		const selectedCompanyData = companyList.value.find((company) => company.Value === companyId);
		if (selectedCompanyData) {
			emit('companyChange', companyId, selectedCompanyData);
		}
	} else {
		// 清空选择时，清除查询条件并展示全部数据
		await loadTreeData();
		// 触发公司变化事件，传递空值表示清空
		emit('companyChange', '', null);
	}
};

// 加载公司列表
const loadCompanyList = async () => {
	if (!props.showCompanySelector) return;

	try {
		const companies = await commonApi().getOrganizations();
		companyList.value = companies;

		// 设置默认选中的公司
		if (props.defaultCompanyId && companies.length > 0) {
			const defaultCompany = companies.find((company: Company) => company.Value === props.defaultCompanyId);
			if (defaultCompany) {
				selectedCompany.value = props.defaultCompanyId;
			}
		}
	} catch (error) {
		console.error('加载公司列表失败:', error);
	}
};

// 加载树形数据
const loadTreeData = async () => {
	if (props.data && props.data.length > 0) {
		treeData.value = props.data;
		emit('dataLoaded', props.data);

		// 如果启用了只展开第一级，设置第一级节点的键值
		if (props.expandFirstLevel) {
			defaultExpandedKeys.value = getFirstLevelKeys(props.data);
		}
		return;
	}

	if (!props.dataSource) return;

	loading.value = true;
	try {
		let currentOrgId = props.orgId;

		// 如果启用了公司选择器且有选中的公司，使用选中的公司ID
		if (props.showCompanySelector && selectedCompany.value) {
			currentOrgId = selectedCompany.value;
		}

		// 构建完整的API URL，包含查询参数
		const buildApiUrl = (baseUrl: string, params: Record<string, any>): string => {
			const queryParams = new URLSearchParams();

			// 添加所有非空参数
			Object.entries(params).forEach(([key, value]) => {
				if (value !== undefined && value !== null && value !== '') {
					queryParams.append(key, String(value));
				}
			});

			const separator = baseUrl.includes('?') ? '&' : '?';
			return `${baseUrl}${separator}${queryParams.toString()}`;
		};

		// 定义所有可能的查询参数
		const queryParams = {
			auth: props.auth,
			orgId: currentOrgId, // 直接传递orgId参数
			// 只有在没有选取公司时才带showCompany参数
			...(currentOrgId ? {} : { showCompany: props.showCompany }),
			// 未来可以轻松添加更多参数
			// groupId: props.groupId,
			// apiVersion: props.apiVersion,
			// 其他参数...
		};

		const apiUrl = buildApiUrl(props.dataSource, queryParams);

		const data = await other.getSelectList(apiUrl, [], false);

		treeData.value = [...data];
		emit('dataLoaded', data);

		// 如果启用了只展开第一级，设置第一级节点的键值
		if (props.expandFirstLevel) {
			defaultExpandedKeys.value = getFirstLevelKeys(data);
		}

		// 设置默认选中
		if (props.defaultSelected) {
			setTimeout(() => {
				treeRef.value?.setCurrentKey(props.defaultSelected);
			}, 100);
		}
	} catch (error) {
		console.error('加载部门树数据失败:', error);
	} finally {
		loading.value = false;
	}
};

// 刷新树形数据
const refreshTree = () => {
	loadTreeData();
};

// 设置当前选中节点
const setCurrentKey = (key: string | number) => {
	treeRef.value?.setCurrentKey(key);
};

// 获取当前选中节点
const getCurrentKey = () => {
	return treeRef.value?.getCurrentKey();
};

// 获取当前选中节点数据
const getCurrentNode = () => {
	return treeRef.value?.getCurrentNode();
};

// 设置选中的公司
const setSelectedCompany = (companyId: string | number) => {
	selectedCompany.value = companyId;
	loadTreeData();
};

// 获取当前选中的公司
const getSelectedCompany = () => {
	return selectedCompany.value;
};

// 监听数据变化
watch(
	() => props.data,
	(newData) => {
		if (newData && newData.length > 0) {
			treeData.value = newData;
			// 如果启用了只展开第一级，设置第一级节点的键值
			if (props.expandFirstLevel) {
				defaultExpandedKeys.value = getFirstLevelKeys(newData);
			}
		}
	},
	{ deep: true }
);

// 监听默认选中变化
watch(
	() => props.defaultSelected,
	(newSelected) => {
		if (newSelected && treeRef.value) {
			treeRef.value.setCurrentKey(newSelected);
		}
	}
);

// 监听 orgId 变化自动刷新树
watch(
	() => props.orgId,
	() => {
		loadTreeData();
	}
);

// 监听公司选择器显示状态变化
watch(
	() => props.showCompanySelector,
	(newValue) => {
		if (newValue) {
			loadCompanyList();
		}
	}
);

// 暴露方法给父组件
defineExpose({
	refreshTree,
	setCurrentKey,
	getCurrentKey,
	getCurrentNode,
	loadTreeData,
	setSelectedCompany,
	getSelectedCompany,
});

onMounted(async () => {
	// 如果启用了公司选择器，先加载公司列表
	if (props.showCompanySelector) {
		await loadCompanyList();
	}
	// 然后加载树形数据
	loadTreeData();
});
</script>

<style scoped lang="scss">
.dept-tree-container {
	height: 100%;
	min-height: 400px;
	display: flex;
	flex-direction: column;
	border: 1px solid #e4e7ed;
	border-radius: 4px;
	background-color: #fff;
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

	.dept-tree-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 8px 12px;
		border-bottom: 1px solid #e4e7ed;
		background-color: #f8f9fa;
		border-radius: 4px 4px 0 0;

		.header-left {
			display: flex;
			align-items: center;
			flex: 1;
		}

		.dept-tree-title {
			font-size: 13px;
			font-weight: 500;
			color: #303133;
		}

		.company-selector {
			display: flex;
			align-items: center;
			margin-left: auto; /* 将公司选择器推到最右侧 */
		}

		.el-button {
			padding: 4px 8px;
			font-size: 12px;
		}
	}

	.dept-tree-content {
		flex: 1;
		overflow-y: auto;
		overflow-x: hidden;
		padding: 4px;
		min-height: 0; /* 确保flex子元素能够正确收缩 */

		.empty-state {
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			height: 200px;
			color: #909399;

			.empty-icon {
				font-size: 48px;
				margin-bottom: 16px;
				opacity: 0.5;
			}

			.empty-text {
				font-size: 14px;
				margin: 0;
			}
		}

		.dept-tree {
			:deep(.el-tree-node__content) {
				height: 28px;
				line-height: 28px;
				padding-left: 6px;
				padding-right: 6px;
				border-radius: 3px;
				margin: 1px 0;
				transition: all 0.2s ease;

				&:hover {
					background-color: #f5f7fa;
				}
			}

			:deep(.el-tree-node__expand-icon) {
				color: #c0c4cc;
				font-size: 12px;
			}

			:deep(.is-current > .el-tree-node__content) {
				background-color: #e6f7ff;
				color: #1890ff;
				border: 1px solid #b3d8ff;
			}

			:deep(.el-tree-node) {
				white-space: nowrap;
			}

			:deep(.el-tree-node__label) {
				font-size: 12px;
				overflow: hidden;
				text-overflow: ellipsis;
			}

			.tree-node-content {
				display: flex;
				align-items: center;
				width: 100%;

				.node-icon {
					margin-right: 4px;
					color: #909399;
					font-size: 11px;
					flex-shrink: 0;
				}

				.node-label {
					flex: 1;
					font-size: 12px;
					overflow: hidden;
					text-overflow: ellipsis;
					white-space: nowrap;
				}

				.node-count {
					color: #909399;
					font-size: 11px;
					margin-left: 4px;
					flex-shrink: 0;
				}
			}
		}
	}
}

// 适配不同屏幕尺寸
@media (max-width: 1200px) {
	.dept-tree-container {
		min-height: 350px;
		height: 100%; /* 保持100%高度 */
	}
}

@media (max-width: 768px) {
	.dept-tree-container {
		min-height: 300px;
		height: 100%; /* 保持100%高度 */

		.dept-tree-header {
			padding: 6px 8px;

			.dept-tree-title {
				font-size: 12px;
			}

			.company-selector {
				.el-select {
					width: 100px !important;
					margin-left: 4px !important;
				}
			}
		}

		.dept-tree-content {
			flex: 1;
			min-height: 0; /* 确保flex子元素能够正确收缩 */

			.dept-tree {
				:deep(.el-tree-node__content) {
					height: 26px;
					line-height: 26px;
					padding-left: 4px;
					padding-right: 4px;
				}

				.tree-node-content {
					.node-label {
						font-size: 11px;
					}
				}
			}
		}
	}
}

@media (max-width: 576px) {
	.dept-tree-container {
		min-height: 200px;
		height: 100%; /* 保持100%高度 */

		.dept-tree-header {
			.header-left {
				flex-direction: row;
				align-items: center;
				gap: 8px;
			}

			.company-selector {
				.el-select {
					width: 120px !important;
					margin-left: auto !important;
				}
			}
		}

		.dept-tree-content {
			flex: 1;
			min-height: 0; /* 确保flex子元素能够正确收缩 */
		}

		// 骨架图样式
		.tree-skeleton {
			padding: 16px 12px;
		}

		.skeleton-level {
			margin-bottom: 8px;

			&:last-child {
				margin-bottom: 0;
			}
		}

		.skeleton-node {
			display: flex;
			align-items: center;
			margin-bottom: 8px;
			position: relative;
			overflow: hidden;

			&:last-child {
				margin-bottom: 0;
			}

			&.level-1 {
				padding-left: 0;
			}

			&.level-2 {
				padding-left: 20px;
			}

			&.level-3 {
				padding-left: 40px;
			}

			// 骨架图动画效果
			&:before {
				content: '';
				position: absolute;
				top: 0;
				left: -100%;
				width: 100%;
				height: 100%;
				background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
				animation: tree-skeleton-loading 1.8s infinite;
			}
		}

		.skeleton-icon {
			width: 16px;
			height: 16px;
			background: #e4e7ed;
			border-radius: 2px;
			margin-right: 8px;
			flex-shrink: 0;
		}

		.skeleton-text {
			height: 16px;
			background: #e4e7ed;
			border-radius: 8px;
			min-width: 60px;
		}

		// 骨架图动画
		@keyframes tree-skeleton-loading {
			0% {
				left: -100%;
			}
			50% {
				left: 100%;
			}
			100% {
				left: 100%;
			}
		}
	}
}

// 暗黑模式样式
html.dark {
	.dept-tree-container {
		background-color: var(--el-bg-color);
		border-color: var(--el-border-color-light);
		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);

		.dept-tree-header {
			background-color: var(--el-bg-color-overlay);
			border-bottom-color: var(--el-border-color-light);

			.dept-tree-title {
				color: var(--el-text-color-primary);
			}
		}

		.dept-tree-content {
			.empty-state {
				color: var(--el-text-color-secondary);
			}

			.dept-tree {
				:deep(.el-tree-node__content) {
					&:hover {
						background-color: var(--el-fill-color-light);
					}
				}

				:deep(.el-tree-node__expand-icon) {
					color: var(--el-text-color-secondary);
				}

				:deep(.is-current > .el-tree-node__content) {
					background-color: var(--el-color-primary-light-9);
					color: var(--el-color-primary);
					border-color: var(--el-color-primary-light-7);
				}

				.tree-node-content {
					.node-icon {
						color: var(--el-text-color-secondary);
					}

					.node-label {
						color: var(--el-text-color-primary);
					}

					.node-count {
						color: var(--el-text-color-secondary);
					}
				}
			}
		}
	}
}
</style>
